vim.api.nvim_command([[packadd nvim-dap-ui]])
local dap = require('dap')
local dapui = require('dapui')

dap.listeners.after.event_initialized['dapui_config'] = function()
   dapui.open()
end
dap.listeners.after.event_terminated['dapui_config'] = function()
   dapui.close()
end
dap.listeners.after.event_exited['dapui_config'] = function()
   dapui.close()
end

-- We need to override nvim-dap's default highlight groups, AFTER requiring nvim-dap for catppuccin.
vim.api.nvim_set_hl(0, 'DapStopped', { fg = '#ABE9B3' })

vim.fn.sign_define('DapBreakpoint', { text = '', texthl = 'DapBreakpoint', linehl = '', numhl = '' })
vim.fn.sign_define(
   'DapBreakpointCondition',
   { text = 'ﳁ', texthl = 'DapBreakpoint', linehl = '', numhl = '' }
)
vim.fn.sign_define(
   'DapBreakpointRejected',
   { text = '', texthl = 'DapBreakpoint', linehl = '', numhl = '' }
)
vim.fn.sign_define('DapLogPoint', { text = '', texthl = 'DapLogPoint', linehl = '', numhl = '' })
vim.fn.sign_define('DapStopped', { text = '', texthl = 'DapStopped', linehl = '', numhl = '' })

dap.adapters.lldb = {
   type = 'executable',
   command = '/usr/bin/lldb-vscode',
   name = 'lldb',
}
dap.configurations.cpp = {
   {
      name = 'Launch',
      type = 'lldb',
      request = 'launch',
      program = function()
         return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
      end,
      cwd = '${workspaceFolder}',
      stopOnEntry = false,
      args = {},

      -- if you change `runInTerminal` to true, you might need to change the yama/ptrace_scope setting:
      --
      --    echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
      --
      -- Otherwise you might get the following error:
      --
      --    Error on launch: Failed to attach to the target process
      --
      -- But you should be aware of the implications:
      -- https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama.html
      runInTerminal = false,
   },
}

dap.configurations.c = dap.configurations.cpp
dap.configurations.rust = dap.configurations.cpp

dap.adapters.go = function(callback, _config)
   local stdout = vim.loop.new_pipe(false)
   local handle
   local pid_or_err
   local port = 38697
   local opts = {
      stdio = { nil, stdout },
      args = { 'dap', '-l', '127.0.0.1:' .. port },
      detached = true,
   }
   handle, pid_or_err = vim.loop.spawn('dlv', opts, function(code)
      stdout:close()
      handle:close()
      if code ~= 0 then
         vim.notify(
            string.format('"dlv" exited with code: %d, please check your configs for correctness.', code),
            vim.log.levels.WARN,
            { title = '[go] DAP Warning!' }
         )
      end
   end)
   assert(handle, 'Error running dlv: ' .. tostring(pid_or_err))
   stdout:read_start(function(err, chunk)
      assert(not err, err)
      if chunk then
         vim.schedule(function()
            require('dap.repl').append(chunk)
         end)
      end
   end)
   -- Wait for delve to start
   vim.defer_fn(function()
      callback({ type = 'server', host = '127.0.0.1', port = port })
   end, 100)
end
-- https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv_dap.md
dap.configurations.go = {
   { type = 'go', name = 'Debug', request = 'launch', program = '${file}' },
   {
      type = 'go',
      name = 'Debug test', -- configuration for debugging test files
      request = 'launch',
      mode = 'test',
      program = '${file}',
   }, -- works with go.mod packages and sub packages
   {
      type = 'go',
      name = 'Debug test (go.mod)',
      request = 'launch',
      mode = 'test',
      program = './${relativeFileDirname}',
   },
}

dap.adapters.python = {
   type = 'executable',
   command = '/usr/bin/python',
   args = { '-m', 'debugpy.adapter' },
}
dap.configurations.python = {
   {
      -- The first three options are required by nvim-dap
      type = 'python', -- the type here established the link to the adapter definition: `dap.adapters.python`
      request = 'launch',
      name = 'Launch file',
      -- Options below are for debugpy, see https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings for supported options

      program = '${file}', -- This configuration will launch the current file if used.
      pythonPath = function()
         -- debugpy supports launching an application with a different interpreter then the one used to launch debugpy itself.
         -- The code below looks for a `venv` or `.venv` folder in the current directly and uses the python within.
         -- You could adapt this - to for example use the `VIRTUAL_ENV` environment variable.
         local cwd = vim.fn.getcwd()
         if vim.fn.executable(cwd .. '/venv/bin/python') == 1 then
            return cwd .. '/venv/bin/python'
         elseif vim.fn.executable(cwd .. '/.venv/bin/python') == 1 then
            return cwd .. '/.venv/bin/python'
         else
            return '/usr/bin/python'
         end
      end,
   },
}
